The Spatial Aggregation Language by Feng Zhao, Christopher Bailey-Kellogg, Ivan Ordonez Listing One // (1.1) Read input points. points = read_points(infile) // (1.2) Aggregate into a Delaunay triangulation; find the // minimal spanning tree. point_trig = aggregate(points, make_mesh_delaunay()) point_mst = mst(point_trig) // (1.3) Classify, keeping close-enough neighbors. good_adj = function(adj) { nearby_ngraph = reachable_ngraph(point_mst, adj, depth) nearby_edges = faces(make_ngraph_geom(nearby_ngraph), 1) edge_lengths = map(nearby_edges, volume) m = average(edge_lengths) sigma = stddev(edge_lengths, m) distance(from(adj), to(adj)) < m + num_devs*sigma } point_classifier = classify(points, make_classifier_transitive(point_mst,good_adj)) // (2.1) Redescribe point classes as trajectories. points_to_traj = redescribe(classes(point_classifier), make_redescribe_op_path_nline(point_mst)) trajs = high_level_objects(points_to_traj) // (2.2) Aggregate trajectories based on point ngraph. traj_ngraph = aggregate(trajs, make_ngraph_connected_substructure(point_mst, points_classifier, points_to_traj)) // (2.3) Classify based on similarity of tangent vectors. same_limit = function(adj) { t1 = from(adj); t2 = to(adj) p1a = end1(t1); p1b = end2(t1) t2_points = localize(points_to_traj, t2) t2_corresponding_p1a = intersection(t2_points, neighbors(point_trig, p1a)) t2_corresponding_p1b = intersection(t2_points, neighbors(point_trig, p1b)) if (size(t2_corresponding_p1a) == 0 || size(t2_corresponding_p1b) == 0) { false } else { tan_1a = tangent(t1, p1a); tan_1b = tangent(t1, p1b) tan_2a = space_centroid(map(p in t2_corresponding_p1a,{ tangent(t2, p) })) tan_2b = space_centroid(map(p in t2_corresponding_p1b,{ tangent(t2, p) })) ((dot(tan_1a, tan_2a)>=angle_thresh} && dot(tan_1b,tan_2b)>=angle_thresh}) || (-dot(tan_1a, tan_2a)>=angle_thresh} && -dot(tan_1b, tan_2b)>=angle_thresh})) } } traj_classifier = classify(trajs, make_classifier_transitive(traj_ngraph, same_limit))